package asm.dump;

import org.ricks.asm.*;
import org.ricks.common.Pair;

import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author chenwei
 * @Description: ASM指令生成器
 * @date 2022/9/1514:04
 */
public class EnumCallDump implements Opcodes {

    public static byte[] dump(List<Pair> pairs) throws Exception {
        List<Pair> sorted = pairs.stream().sorted(new Comparator<Pair>() {
            @Override
            public int compare(Pair o1, Pair o2) {
                return (short)o1.getKey() - (short)o2.getKey();
            }
        }).collect(Collectors.toList());
        ClassWriter classWriter = new ClassWriter(0);
        FieldVisitor fieldVisitor;

        classWriter.visit(V17, ACC_PUBLIC | ACC_SUPER, "org/ricks/dispatch/EnumCall", null, "java/lang/Object", null);

        classWriter.visitSource("EnumCall.java", null);

        for (Pair<Short,String> pair: sorted) {
            fieldVisitor  = classWriter.visitField(ACC_PUBLIC | ACC_FINAL | ACC_STATIC, pair.getValue(), "S", null, pair.getKey());
            fieldVisitor.visitEnd();
        }

        MethodVisitor methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
        methodVisitor.visitCode();
        Label label0 = new Label();
        methodVisitor.visitLabel(label0);
        methodVisitor.visitLineNumber(7, label0);
        methodVisitor.visitVarInsn(ALOAD, 0);
        methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
        methodVisitor.visitInsn(RETURN);
        Label label1 = new Label();
        methodVisitor.visitLabel(label1);
        methodVisitor.visitLocalVariable("this", "Lorg/demon/dispatch/EnumCall;", null, label0, label1, 0);
        methodVisitor.visitMaxs(1, 1);
        methodVisitor.visitEnd();

        classWriter.visitEnd();

        return classWriter.toByteArray();
    }
}
